namespace Skymate.Mvc.Controllers.Dynamic.Scripting.jQuery
{
    using System.Text;

    using Skymate.Extensions;
    using Skymate.Mvc;
    using Skymate.Mvc.Controllers.Dynamic;
    using Skymate.Mvc.Controllers.Dynamic.Scripting;

    internal class JQueryActionScriptGenerator
    {
        private readonly DynamicApiControllerInfo _controllerInfo;
        private readonly DynamicApiActionInfo _actionInfo;

        private const string JsMethodTemplate =
@"    serviceNamespace.{jsMethodName} = function({jsMethodParameterList}) {
        return abp.ajax($.extend({
{ajaxCallParameters}
        }, ajaxParams));
    };";

        public JQueryActionScriptGenerator(DynamicApiControllerInfo controllerInfo, DynamicApiActionInfo actionInfo)
        {
            this._controllerInfo = controllerInfo;
            this._actionInfo = actionInfo;
        }

        public virtual string GenerateMethod()
        {
            var jsMethodName = this._actionInfo.ActionName.ToCamelCase();
            var jsMethodParameterList = ActionScriptingHelper.GenerateJsMethodParameterList(this._actionInfo.Method, "ajaxParams");

            var jsMethod = JsMethodTemplate
                .Replace("{jsMethodName}", jsMethodName)
                .Replace("{jsMethodParameterList}", jsMethodParameterList)
                .Replace("{ajaxCallParameters}", this.GenerateAjaxCallParameters());

            return jsMethod;
        }

        protected string GenerateAjaxCallParameters()
        {
            var script = new StringBuilder();
            
            script.AppendLine("            url: abp.appPath + '" + ActionScriptingHelper.GenerateUrlWithParameters(this._controllerInfo, this._actionInfo) + "',");
            script.AppendLine("            type: '" + this._actionInfo.Verb.ToString().ToUpperInvariant() + "',");

            if (this._actionInfo.Verb == HttpVerb.Get)
            {
                script.Append("            data: " + ActionScriptingHelper.GenerateBody(this._actionInfo));
            }
            else
            {
                script.Append("            data: JSON.stringify(" + ActionScriptingHelper.GenerateBody(this._actionInfo) + ")");                
            }
            
            return script.ToString();
        }
    }
}